
/**
 * 处理菜单组件拖拽动作
 * @author  韦胜健
 * @date    2021/12/22 23:36
 */
export function useVisualEditorMenuDraggier({ hooks, methods }) {

  let staticState = null;

  let ejectOnDropBaseContainer = null;

  const handler = {
    dragStart: ({ event, component }) => {
      // event.stopPropagation();
      // event.preventDefault();
      // event.dataTransfer.effectAllowed = 'move'
      event.dataTransfer.dropEffect = 'move'
      // debugger
      if (staticState?.isDrag) return
      staticState = {
        isDrag: true,
        component,
      };
      hooks.onDragstart.exec(undefined);
      ejectOnDropBaseContainer = hooks.onDropBaseContainer.use(async ({ dropUpdater }) => {
        const { code, group, name, defaultData } = staticState.component;
        const data = await methods.createComponentData({ code, group, name, ...defaultData, });
        dropUpdater(data);
        // 拖拽完成，还原拖拽前数据，避免数据污染
        handler.reset()
      });
    },
    dragEnd: () => {
      handler.reset()
    },
    reset: () => {
      hooks.onDragend.exec(undefined);
      !!ejectOnDropBaseContainer && ejectOnDropBaseContainer();
      staticState = null
      ejectOnDropBaseContainer = null
    },
    mousedown: ({ event, component }) => {
      event.stopPropagation();
      event.preventDefault();
      staticState = {
        event,
        currentTarget: event.currentTarget,
        isMove: null,
        component,
      };
      window.addEventListener('mousemove', handler.mousemove);
      window.addEventListener('mouseup', handler.mouseup);
    },
    mousemove: (e) => {
      if (!staticState) {return;}
      const durX = e.clientX - staticState.event.clientX;
      const durY = e.clientY - staticState.event.clientY;
      if (!staticState.isMove) {
        if (durX > 20 || durY > 20) {
          const sourceEl = staticState.currentTarget;
          const moveEl = sourceEl.cloneNode(true);
          moveEl.setAttribute('data-draggier', '');
          document.body.appendChild(moveEl);
          const { height, width, top, left } = sourceEl.getBoundingClientRect();
          staticState.isMove = { el: moveEl, startX: left, startY: top };
          const styles = {
            position: 'fixed',
            zIndex: 9999,
            width: `${width}px`,
            height: `${height}px`,
            top: `${top}px`,
            left: `${left}px`,
            pointerEvents: 'none',
            opacity: '0.5',
          };
          Object.assign(moveEl.style, styles);

          hooks.onDragstart.exec(undefined);

          ejectOnDropBaseContainer = hooks.onDropBaseContainer.use(async ({ dropUpdater }) => {
            const { code, group, name, defaultData } = staticState.component;
            const data = await methods.createComponentData({ code, group, name, ...defaultData, });
            dropUpdater(data);
          });
        }
      }
      if (!staticState.isMove) {return;}
      Object.assign(staticState.isMove.el.style, {
        top: `${staticState.isMove.startY + durY}px`,
        left: `${staticState.isMove.startX + durX}px`,
      });
    },
    mouseup: () => {
      if (!!staticState) {
        staticState.isMove?.el.parentNode?.removeChild(staticState.isMove?.el);
        staticState = null;
      }
      hooks.onDragend.exec(undefined);
      window.removeEventListener('mousemove', handler.mousemove);
      window.removeEventListener('mouseup', handler.mouseup);
      !!ejectOnDropBaseContainer && ejectOnDropBaseContainer();
    },
  };

  return {
    onMousedown: handler.mousedown,
    onDragstart: handler.dragStart,
    onDragend: handler.dragEnd
  };
}
